﻿using UnityEngine;
using System.Collections.Generic;

public enum EBeatType
{
    Regular_L = 1,
    Regular_R = 2,
    Little_L = 3,
    Little_R = 4,
    HighHeel_L = 5,
    HighHeel_R = 6
}

public enum EChannel
{
    Channel_1 = 1,
    Channel_2 = 2,
    Channel_3 = 3,
    Channel_4 = 4,
    Channel_5 = 5,
    Channel_6 = 6
}

public class BeatConfig
{
    public float BPM;
    public List<BeatModel> BeatModelList { get; set; }
}
public class BeatModel
{
    public int Count { get; set; }
    public EBeatType Type { get; set; }
    public EChannel Channel { get; set; }
    public int BeatTime { get; set; }

}
public class BeatManager : Singleton<BeatManager>
{
    private Transform tr_SpawnPoint;
    private Transform tr_TargetPoint;
    private Transform SpawnPoint_Channel_1;
    private Transform TargetPoint_Channel_1;

    private Transform SpawnPoint_Channel_2;
    private Transform TargetPoint_Channel_2;

    private Transform SpawnPoint_Channel_3;
    private Transform TargetPoint_Channel_3;

    private Transform SpawnPoint_Channel_4;
    private Transform TargetPoint_Channel_4;

    private Transform SpawnPoint_Channel_5;
    private Transform TargetPoint_Channel_5;

    private Transform SpawnPoint_Channel_6;
    private Transform TargetPoint_Channel_6;

    private List<BeatSpawner> SpawnerList;
    private void Awake()
    {
        SpawnerList = new List<BeatSpawner>();
        Transform beatSpawnerRoot = GameObject.Find("BeatSpawnerRoot").transform;
        foreach (Transform child in beatSpawnerRoot)
        {
            SpawnerList.Add(child.GetComponent<BeatSpawner>());
        }

        GameObject go_SpawnPoint = GameObject.Find("SpawnPoint");
        tr_SpawnPoint = go_SpawnPoint.transform;
        GameObject go_TargetPoint = GameObject.Find("TargetPoint");
        tr_TargetPoint = go_TargetPoint.transform;

        SpawnPoint_Channel_1 = tr_SpawnPoint.Find("Spawn_1");
        SpawnPoint_Channel_2 = tr_SpawnPoint.Find("Spawn_2");
        SpawnPoint_Channel_3 = tr_SpawnPoint.Find("Spawn_3");
        SpawnPoint_Channel_4 = tr_SpawnPoint.Find("Spawn_4");
        SpawnPoint_Channel_5 = tr_SpawnPoint.Find("Spawn_5");
        SpawnPoint_Channel_6 = tr_SpawnPoint.Find("Spawn_6");

        TargetPoint_Channel_1 = tr_TargetPoint.Find("Target_1");
        TargetPoint_Channel_2 = tr_TargetPoint.Find("Target_2");
        TargetPoint_Channel_3 = tr_TargetPoint.Find("Target_3");
        TargetPoint_Channel_4 = tr_TargetPoint.Find("Target_4");
        TargetPoint_Channel_5 = tr_TargetPoint.Find("Target_5");
        TargetPoint_Channel_6 = tr_TargetPoint.Find("Target_6");
    }

    public Vector3 GetChannelSpawnPos(EChannel newChannel)
    {
        Vector3 resultVec = Vector3.zero;
        switch (newChannel)
        {
            case EChannel.Channel_1:
                resultVec = SpawnPoint_Channel_1.position;
                break;

            case EChannel.Channel_2:
                resultVec = SpawnPoint_Channel_2.position;
                break;

            case EChannel.Channel_3:
                resultVec = SpawnPoint_Channel_3.position;
                break;

            case EChannel.Channel_4:
                resultVec = SpawnPoint_Channel_4.position;
                break;

            case EChannel.Channel_5:
                resultVec = SpawnPoint_Channel_5.position;
                break;

            case EChannel.Channel_6:
                resultVec = SpawnPoint_Channel_6.position;
                break;
        }
        return resultVec;
    }

    public Vector3 GetChannelTargetPos(EChannel newChannel)
    {
        Vector3 resultVec = Vector3.zero;
        switch (newChannel)
        {
            case EChannel.Channel_1:
                resultVec = TargetPoint_Channel_1.position;
                break;

            case EChannel.Channel_2:
                resultVec = TargetPoint_Channel_2.position;
                break;

            case EChannel.Channel_3:
                resultVec = TargetPoint_Channel_3.position;
                break;

            case EChannel.Channel_4:
                resultVec = TargetPoint_Channel_4.position;
                break;

            case EChannel.Channel_5:
                resultVec = TargetPoint_Channel_5.position;
                break;

            case EChannel.Channel_6:
                resultVec = TargetPoint_Channel_6.position;
                break;
        }
        return resultVec;
    }
    public void StartSpawnBeat(float beatBeforeTriggerDuration, BeatConfig newBeatsConfig)
    {
        if (newBeatsConfig != null && newBeatsConfig.BeatModelList.Count >= 1)
        {
            for (int i = 0; i < SpawnerList.Count; i++)
            {
                if (SpawnerList[i].SpawnedCount == 0)
                {
                    for (int j = 0; j < newBeatsConfig.BeatModelList.Count; j++)
                    {
                        if (newBeatsConfig.BeatModelList[j].Type == SpawnerList[i].eBeatType)
                        {
                            float firstBeatTime = newBeatsConfig.BeatModelList[j].BeatTime / 1000.0f;
                            SpawnerList[i].DelaySpawnBeat(firstBeatTime, beatBeforeTriggerDuration, newBeatsConfig);
                            break;
                        }
                    }
                }
            }
        }
    }

    public void AutoStart_34()
    {
        BeatSpawner spawner3 = SpawnerList[2];
        BeatSpawner spawner4 = SpawnerList[3];

        Timer.Register(1.7f, () => { spawner3.SpawnBeat(1.7f); }, null, true, false, this);
        Timer.Register(1.7f, () => { spawner4.DelaySpawnBeat(0.85f, 1.7f); }, null, true, false, this);
    }

    public void AutoStart_56()
    {
        BeatSpawner spawner5 = SpawnerList[4];
        BeatSpawner spawner6 = SpawnerList[5];

        Timer.Register(1.2f, () => { spawner5.SpawnBeat(1.2f); }, null, true, false, this);
        Timer.Register(1.2f, () => { spawner6.DelaySpawnBeat(0.6f, 1.2f); }, null, true, false, this);
    }

    private void OnDestroy()
    {
        Timer.CancelAllRegisteredTimers();
    }
}
